package io.github.flylinran.common.utils;

import lombok.AccessLevel;
import lombok.NoArgsConstructor;

@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class ShortenUtil {

    private static final String ALPHABET = "bcdfghjkmnpqrstvwxyzBCDFGHJKLMNPQRSTVWXYZ23456789-_"; //"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    private static final int BASE = ALPHABET.length();

    /**
     * 对ID进行自定义编码
     *
     * @param num ID
     * @return 编码后的字符串
     */
    public static String encode(int num) {
        StringBuilder sb = new StringBuilder();
        while (num > 0) {
            sb.append(ALPHABET.charAt(num % BASE));
            num /= BASE;
        }
        // 补齐
        for (int i = sb.length(); i < 6; i++) {
            sb.append(ALPHABET.charAt(0));
        }
        return sb.reverse().toString();
    }

    /**
     * 对字符串进行自定义解码
     *
     * @param str 编码后的字符串
     * @return 解码后的ID
     */
    public static int decode(String str) {
        int num = 0;
        for (int i = 0; i < str.length(); i++)
            num = num * BASE + ALPHABET.indexOf(str.charAt(i));
        return num;
    }

    private static final String[] chars = {"a", "b", "c", "d", "e", "f", "g", "h",
            "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t",
            "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5",
            "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H",
            "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T",
            "U", "V", "W", "X", "Y", "Z"
    };
    private static final String key = "";

    /**
     * shorturl way 2
     *
     * @param url 原始URL
     * @return 短链数组，长度为4
     */
    public static String[] buildWithMd5Util(String url) {
        if (url == null) {
            throw new IllegalArgumentException("the url can't null");
        }
        //先得到url的32个字符的md5码
        String md5 = Md5Util.encrypt(url, key);
        String[] result = new String[4];

        //将32个字符的md5码分成4段处理，每段8个字符
        for (int i = 0; i < 4; i++) {
            int offset = i * 8;
            String sub = md5.substring(offset, offset + 8);
            long sub16 = Long.parseLong(sub, 16); //将sub当作一个16进制的数，转成long
            // & 0X3FFFFFFF，去掉最前面的2位，只留下30位
            sub16 &= 0X3FFFFFFF;
            StringBuilder sb = new StringBuilder();
            //将剩下的30位分6段处理，每段5位
            for (int j = 0; j < 6; j++) {
                //得到一个 <= 61的数字
                long t = sub16 & 0x0000003D;
                sb.append(chars[(int) t]);
                sub16 >>= 5;  //将sub16右移5位
            }
            result[i] = sb.toString();
        }
        return result;
    }
}
